package cn.wzvtcsoft.base;

import cn.wzvtcsoft.common.util.BeanUtil;
import cn.wzvtcsoft.common.util.PageUtil;
import cn.wzvtcsoft.common.vo.PageQueryParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.Collection;
import java.util.List;


/**
 * @author swxu_2005@163.com
 * BaseService接口的默认实现
 */
public class BaseServiceImpl<E extends BaseEntity, R extends BaseRepository<E, Long>> implements BaseService<E> {
  @Autowired
  protected R thisRepository;

  @Override
  public E getOne(Long id) {
    return thisRepository.getOne(id);
  }

  @Override
  public List<E> findAll() {
    return thisRepository.findAll();
  }

  @Override
  public Page<E> listByConditionAndPage(PageQueryParam<E> pageQueryParam) {
    Pageable pageable = PageUtil.initPage(pageQueryParam.getPageParam());
    E queryCondition = pageQueryParam.getEntityParam();

        /* Page<E> results = thisRepository.findAll(new Specification<E>() {
            @Override
            public Predicate toPredicate(Root<E> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
                Path<String> usernameField = root.get("number");

                List<Predicate> list = new ArrayList<>();
                if (!StringUtils.isEmpty(queryCondition.getNumber())) {
                    list.add(cb.like(usernameField, '%' + queryCondition.getNumber() + '%'));
                }

                Predicate[] arr = new Predicate[list.size()];
                cq.where(list.toArray(arr));
                return null;
            }
        }, pageable); */

    return null;
  }

  @Override
  public E insert(E e) {
    beforeInsertOrUpdate(e);
    return thisRepository.saveAndFlush(e);
  }

  @Override
  public E update(E newItem) {
    E oldItem = thisRepository.getOne(newItem.getId());
    BeanUtil.copyProperties(newItem, oldItem);
    beforeInsertOrUpdate(oldItem);
    return thisRepository.saveAndFlush(oldItem);
  }

  /**
   * 实体中可能有OneToMany的属性，这些属性在父实体对象insert或update前要先确保其parent属性已设置
   * 具体设置，在子类中实现，默认无操作
   */
  protected void beforeInsertOrUpdate(E e) {

  }

  @Override
  public void delete(E e) {
    thisRepository.delete(e);
  }

  @Override
  public void deleteAll(Collection<E> es) {
    thisRepository.deleteAll(es);
  }
}
